<!DOCTYPE html>
<html lang="zh-cn">

<head>
    <meta charset="utf-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">

    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <meta name="description" content="ssdut dsa web" />
    <meta name="author" content="" />

    <title>ssdut.DSA/二叉树/堆</title>
    <link rel="stylesheet" href="../assets/css/fonts/linecons/css/linecons.css">
    <link rel="stylesheet" href="../assets/css/fonts/fontawesome/css/font-awesome.min.css">
    <link rel="stylesheet" href="../assets/css/bootstrap.css">
    <link rel="stylesheet" href="../assets/css/xenon-core.css">
    <link rel="stylesheet" href="../assets/css/xenon-forms.css">
    <link rel="stylesheet" href="../assets/css/xenon-components.css">
    <link rel="stylesheet" href="../assets/css/xenon-skins.css">
    <link rel="stylesheet" href="../assets/css/custom.css">
    <link rel="stylesheet" type="text/css" href="../assets/css/stylesheet.css">
    <link rel="stylesheet" type="text/css" href="../assets/css/common.css">
    <link rel="stylesheet" href="../assets/css/viz-1.0.1.css">
    <link rel="stylesheet" href="../assets/css/visual.css">
    <link rel="stylesheet" href="../assets/css/drawgraph.css">


    <script src="../assets/js/jquery-3.3.1.min.js"></script>

</head>

<body class="page-body">
    <div class="page-container">
        <!-- add class"sidebar-collapsed" to close sidebar by default,"chat-visible" to make chat appear always -->

        <!-- Add"fixed" class to make the sidebar fixed always to the browser viewport. -->
        <!-- Adding class"toggle-others" will keep only one menu item open at a time. -->
        <!-- Adding class"collapsed" collapse sidebar root elements and show only icons. -->
        <div class="sidebar-menu toggle-others fixed">

            <div class="sidebar-menu-inner">

                <header class="logo-env">
                    <!-- logo -->
                    <div class="logo">
                        <a href="../" class="logo-expanded">
                            <img src="../assets/images/logo@2x.png" width="80" alt="" />
                        </a>

                        <a href="../" class="logo-collapsed">
                            <img src="../assets/images/logo-collapsed@2x.png" width="40" alt="" />
                        </a>
                    </div>
                  
                </header>
                <ul id="main-menu" class="main-menu">
                    <!-- add class"multiple-expanded" to allow multiple submenus to open -->
                    <!-- class"auto-inherit-active-class" will automatically add"active" class for parent elements who are marked already with class"active" -->
                    <li >
                        <a href="../index.html">
                            <i class="fa-home"></i>
                            <span class="title">首页</span>
                        </a>
                    </li>
                    <li>
                        <a href="../list/ll.html">
                            <i class="fa-chain"></i>
                            <span class="title">线性表</span>
                        </a>
                        <ul>
                            <li>
                                <a href="../list/ll.html">
                                    <span class="title">单链表</span>
                                </a>
                            </li>
                            <li>
                                <a href="../list/stack.html">
                                    <span class="title">栈</span>
                                </a>
                            </li>
                            <li>
                                <a href="../list/queue.html">
                                    <span class="title">队列</span>
                                </a>
                            </li>
                            <li>
                                <a href="../list/dll.html">
                                    <span class="title">双向链表</span>
                                </a>
                            </li>
                            <li>
                                <a href="../list/deque.html">
                                    <span class="title">双端队列</span>
                                </a>
                            </li>

                        </ul>
                    </li>
                    <li class="opened active">
                        <a href="../tree/bst.html">
                            <i class="fa-sitemap"></i>
                            <span class="title">二叉树</span>
                        </a>
                        <ul>
                            <li>
                                <a href="../tree/bst.html">
                                    <span class="title">二叉搜索树</span>
                                </a>
                            </li>
                            <li>
                                <a href="../tree/avl.html">
                                    <span class="title">平衡二叉搜索树</span>
                                </a>
                            </li>
                            <li class="active">
                                <a href="../tree/heap.html">
                                    <span class="title">堆</span>
                                </a>
                            </li>
                        </ul>
                    </li>
                    <li>
                        <a href="../graph/graphds.html">
                            <i class="fa-share-alt"></i>
                            <span class="title">图</span>
                        </a>
                        <ul>
                            <li>
                                <a href="../graph/graphds.html">
                                    <span class="title">图的数据结构</span>
                                </a>
                            </li>
                            <li>
                                <a href="../graph/dfsbfs.html">
                                    <span class="title">图的遍历</span>
                                </a>
                            </li>
                            <li>
                                <a href="../graph/mst.html">
                                    <span class="title">最小生成树</span>
                                </a>
                            </li>
                            <li>
                                <a href="../graph/sssp.html">
                                    <span class="title">最短路径</span>
                                </a>
                            </li>
                            <li>
                                <a href="../graph/maxflow.html">
                                    <span class="title">网络最大流</span>
                                </a>
                            </li>
                        </ul>
                    </li>
                    <li>
                        <a href="../hashtable/lp.html">
                            <i class="fa-random"></i>
                            <span class="title">散列表</span>                          
                        </a>
                        <ul>
                            <li>
                                <a href="../hashtable/lp.html">
                                    <span class="title">线性探查</span>
                                </a>
                            </li>
                            <li>
                                <a href="../hashtable/qp.html">
                                    <span class="title">二次探查</span>
                                </a>
                            </li>
                            <li>
                                <a href="../hashtable/dh.html">
                                    <span class="title">双散列</span>
                                </a>
                            </li>
                            <li>
                                <a href="../hashtable/sc.html">
                                    <span class="title">分离链接</span>
                                </a>
                            </li>
                        </ul>
                    </li>
                    <li >
                        <a href="../sorting/bubble.html" >
                            <i class="fa-sort-amount-asc"></i>
                            <span class="title">排序</span>
                        </a>
                        <ul>
                            <li>
                                <a href="../sorting/bubble.html">
                                    <span class="title">冒泡排序</span>
                                </a>
                            </li>
                            <li>
                                <a href="../sorting/selection.html">
                                    <span class="title">选择排序</span>
                                </a>
                            </li>
                            <li>
                                <a href="../sorting/insertion.html">
                                    <span class="title">插入排序</span>
                                </a>
                            </li>
                            <li>
                                <a href="../sorting/merge.html">
                                    <span class="title">归并排序</span>
                                </a>
                            </li>
                            <li>
                                <a href="../sorting/quick.html">
                                    <span class="title">快速排序</span>
                                </a>
                            </li>
                            <li >
                                <a href="../sorting/radix.html" >
                                    <span class="title">基数排序</span>
                                </a>
                            </li>
                        </ul>
                    </li>             
                </ul>
            </div>
        </div>

        <div class="main-content">

            <!-- User Info, Notifications and Menu Bar -->
          
                <div class="row" style="margin:-30px -30px 0 -30px; background-color: #FFF; padding:15px 10px 10px; ">
                    <div class="col-auto">
                        <ul class="user-info-menu left-links list-inline list-unstyled">
                            <li class="hidden-sm hidden-xs">
                                <a href="#" data-toggle="sidebar">
                                    <i class="fa-bars"></i>
                                </a>
                            </li>
                        </ul>        
                    </div>
                    <!-- Left links for user info navbar -->
                    <div class="col-auto">
                        <h4 id="page-title" >链表</h4>
                    </div>
                    <div class="col-auto me-auto">
                        <div id="current-action" ></div>
                    </div>               
                    <div class="col-auto" >
                                    <!-- Right links for user info navbar -->              
                        <div id="speed-control">
                            减速
                            <div id="speed-input" class="ui-slider ui-corner-all ui-slider-horizontal ui-widget ui-widget-content">
                                <span tabindex="0" class="ui-slider-handle ui-corner-all ui-state-default" style="left: 72.2222%;"></span>
                            </div>
                            加速
                        </div>              
                    </div>
                </div>
            

            <script type="text/javascript">
                jQuery(document).ready(function($) {     
                    // Charts
                    var xenonPalette = ['#68b828', '#7c38bc', '#0e62c7', '#fcd036', '#4fcdfc', '#00b19d', '#ff6264', '#f7aa47'];
                    // Pageviews Visitors Chart
     
                        $("#page-title").text('堆');
                });
             

                   


               
            </script>

            <div class="row">

             
                <div id="dark-overlay"></div>


                <div id="viz">

                </div>
                

                <div id="overlay" hidden="" style="opacity: 0; display: none;"></div>


                <div id="popup" hidden="">
                    <div id="popup-content"></div>
                    <span id="hide-popup" hidden="" style="background-color: rgb(255, 138, 39);">X <u>关闭</u></span>
                </div>
         

                <script>
                    var PHP_DOMAIN ="";

                    // surprise colour!
                    // Referenced to in  home.js and viz.js also
                    var colourArray = ["#52bc69","#d65775" /*"#ed5a7d"*/ ,"#2ebbd1","#d9513c","#fec515","#4b65ba","#ff8a27","#a7d41e"]; // green, pink, blue, red, yellow, indigo, orange, lime

                    function disableScroll() {
                        $('html').css('overflow', 'hidden');
                    }

                    function enableScroll() {
                        $('html').css('overflow', 'visible');
                    }

                    function replaceAll(find, replace, str) {
                        return str.replace(new RegExp(find, 'g'), replace);
                    }

                    function getColours() {
                        var generatedColours = new Array();
                        while (generatedColours.length < 4) {
                            var n = (Math.floor(Math.random() * colourArray.length));
                            if ($.inArray(n, generatedColours) == -1)
                                generatedColours.push(n);
                        }
                        return generatedColours;
                    }

                    function isOn(value, position) {
                        return (value >> position) & 1 === 1;
                    }

                    function customAlert(msg) {
                        $('#custom-alert p').html(msg);
                        var m = -1 * ($('#custom-alert').outerHeight() / 2);
                        $('#custom-alert').css('margin-top', m + 'px');
                        $('#dark-overlay').fadeIn(function() {
                            $('#custom-alert').fadeIn(function() {
                                setTimeout(function() {
                                    $('#custom-alert').fadeOut(function() {
                                        $('#dark-overlay').fadeOut();
                                    });
                                }, 1000);
                            });
                        });
                    }

                    function showLoadingScreen() {
                        $('#loading-overlay').show();
                        $('#loading-message').show();
                    }

                    function hideLoadingScreen() {
                        $('#loading-overlay').hide();
                    }

                    function commonAction(retval, msg) {
                        //setTimeout(function() {
                        if (retval) { // mode =="exploration" && // now not only for exploration mode, but check if this opens other problems
                         
                            $('#current-action').html(mode =="exploration" ? msg : ("e-Lecture Example (auto play until done)<br>" + msg));
                            $('#progress-bar').slider("option","max", gw.getTotalIteration() - 1);
                            triggerRightPanels();
                            isPlaying = true;
                        }
                        //}, 500);
                    }

                    function getQueryVariable(variable) {
                        var query = window.location.search.substring(1);
                        var vars = query.split('&');
                        for (var i = 0; i < vars.length; i++) {
                            var pair = vars[i].split('=');
                            if (decodeURIComponent(pair[0]) == variable)
                                return decodeURIComponent(pair[1]);
                        }
                        return"";
                    }

                    var generatedColours = getColours();
                    var surpriseColour = colourArray[generatedColours[0]];
                    var colourTheSecond = colourArray[generatedColours[1]];
                    var colourTheThird = colourArray[generatedColours[2]];
                    var colourTheFourth = colourArray[generatedColours[3]];

                    $(function() {
                       

                        // title
                        $('#title a').click(function() {
                            $('#title a').removeClass('selected-viz');
                            $(this).addClass('selected-viz');
                            // temporary quick fix for Google Chrome Aug 2016 issue...
                            setTimeout(function() {
                                document.body.style.zoom ="100.1%";
                            }, 100); // force resize/redraw...
                            setTimeout(function() {
                                document.body.style.zoom ="100%";
                            }, 600);
                        });

                        // overlays stuffs
                        $('#trigger-about').click(function() {
                            if ($(window).width() > 600) {
                                $('#dark-overlay').fadeIn(function() {
                                    $('#about').fadeIn();
                                });
                            } else
                                alert('Sorry, this dialog is too big. Please load it on bigger screen');
                        });

                        $('#trigger-team').click(function() {
                            if ($(window).width() > 600) {
                                $('#dark-overlay').fadeIn(function() {
                                    $('#team').fadeIn();
                                });
                            } else
                                alert('Sorry, this dialog is too big. Please load it on bigger screen');
                        });

                        $('#trigger-terms').click(function() {
                            if ($(window).width() > 600) {
                                $('#dark-overlay').fadeIn(function() {
                                    $('#termsofuse').fadeIn();
                                });
                            } else
                                alert('Sorry, this dialog is too big. Please load it on bigger screen');
                        });

                        $('.close-overlay').click(function() {
                            $('.overlays').fadeOut(function() {
                                $('#dark-overlay').fadeOut();
                            });
                        });

                        $('#dark-overlay').click(function() {
                            $('.overlays').fadeOut();
                            $('#dark-overlay').fadeOut();
                        });
                    });
                </script>




                <script>
                    window.onpopstate = function(event) {
                        var slide = event.state['slide'];
                        openSlide(slide, function() {
                            runSlide(slide);
                        });
                    };

                    function getUrlParameter(sParam) {
                        var sPageURL = decodeURIComponent(window.location.search.substring(1)),
                            sURLVariables = sPageURL.split('&'),
                            sParameterName, i;

                        for (i = 0; i < sURLVariables.length; i++) {
                            sParameterName = sURLVariables[i].split('=');
                            if (sParameterName[0] === sParam) return sParameterName[1] === undefined ? true : sParameterName[1];
                        }
                    };

                    function pushState(slideValue) {
                        var url = '/zh/list';
                        if (typeof slideValue != 'undefined' && slideValue != null) url += '?slide=' + slideValue;
                        window.history.pushState({
                            slide: slideValue
                        },"slide" + slideValue, url);
                    }

                    function showPopup(callback) {
                        $('#popup').fadeIn(100, callback);
                    }

                    function hidePopup(callback) {
                        $('#popup').fadeOut(100, callback);
                    }

                    $(function() {
                        var slide = getUrlParameter('slide');

          

                        $('.mcq-submit').click(function() {
                            var questionId = parseInt($(this).attr('id').split('-')[1]);
                            var answer = $('#mcq-answer-' + questionId).val();
                            var userAnswer = $('input[type=radio][name=mcq-' + questionId + '-choice]:checked').val();

                            if (answer === userAnswer) {
                                $('#answer-status-' + questionId).html('<font color="green"><b>Correct!</b></font>');
                            } else {
                                $('#answer-status-' + questionId).html('<font color="red"><b>Wrong Answer! Try again...</b></font>');
                            }
                            $('#answer-status-' + questionId).show();
                            setTimeout(function() {
                                $('#answer-status-' + questionId).fadeOut(1000);
                            }, 1000);
                        });

                        $('.msq-submit').click(function() {
                            var questionId = parseInt($(this).attr('id').split('-')[1]);
                            var answer = $('#msq-answer-' + questionId).val();

                            var answers = [];
                            $('input[type=checkbox][class=msq-choice]:checked').each(function() {
                                answers.push($(this).attr('id').split('-')[3]);
                            });
                            answers.sort();
                            var userAnswer = answers.join(',');

                            if (answer === userAnswer) {
                                $('#answer-status-' + questionId).html('<font color="green">Correct!</font>');
                            } else {
                                $('#answer-status-' + questionId).html('<font color="red">Wrong Answer! Try again...</font>');
                            }
                            $('#answer-status-' + questionId).show();
                            setTimeout(function() {
                                $('#answer-status-' + questionId).fadeOut(1000);
                            }, 1000);
                        });

                      

                        $('#hide-popup').click(function() {
                            hidePopup();
                        });

                        $('#popup').hover(function() {
                            $('#hide-popup').show();
                        }, function() {
                            $('#hide-popup').hide();
                        });




                        // temporary quick fix for Google Chrome Aug 2016 issue..., put at last part so that everything else has been loaded
                        // setTimeout(function(){ document.body.style.zoom ="100.1%"; }, 500);
                        // setTimeout(function(){ document.body.style.zoom ="100%"; }, 600);
                        // I turn it off on 14 June 2018, seems 'ok'?
                    });

               

                    function adjustPopupToImageSize() {
                        var width = $('#popup-image').prop('width');
                        var height = $('#popup-image').prop('height');
                        $('#popup').width(width + 20);
                        $('#popup').height(height + 20);
                        if (width == 0 && height == 0) {
                            setTimeout(adjustPopupToImageSize, 200);
                        } else {
                            showPopup();
                        }
                    }

                    function POPUP_IMAGE(url) {
                        $('#popup-content').html('<img id="popup-image" src="' + url + '">');
                        adjustPopupToImageSize();
                    }

                    function URL(url) {
                        window.open(url, '_blank');
                    }

                </script>


            </div>






            <!-- Main Footer -->
            <!-- Choose between footer styles:"footer-type-1" or"footer-type-2" -->
            <!-- Add class"sticky" to  always stick the footer to the end of page (if page contents is small) -->
            <!-- Or class"fixed" to  always fix the footer to the end of page -->
            <footer class="main-footer sticky footer-type-2 sticky fixed">

                <div class="footer-inner">
                    <div class="row">
                        <div class="col-auto">
                            <div class="btn-group dropdown dropup">                               
                                <a id="actions-toggle" class="btn btn-sm btn-info dropdown-toggle " data-bs-toggle="dropdown"  data-bs-auto-close="outside" aria-haspopup="true" aria-expanded="false">                            
                                    操作                                                      
                                </a>                                    
                                <div id="actions" class="dropdown-menu">
                                    <div class="dropdown dropend">                                        
                                        <a  class="dropdown-item dropdown-toggle" href="#"_id="dropdown-create" data-bs-toggle="dropdown" aria-haspopup="true" aria-expanded="false">
                                            创建 O(N log N)</a>
                                        <div class="dropdown-menu" aria-labelledby="dropdown-create" style="min-width: 300px;">
                                           
                                            <div id="create-random" class="dropdown-item" onclick="createNlogNRandom()" >
                                                <a>随机</a>
                                            </div>
                                            <div id="create-random-sorted" class="dropdown-item" onclick="createNlogNSample()" >
                                                <a>已排序</a>
                                            </div>
                                          
                                            <div class="dropdown-divider"></div>
                                            <div id="create-from-arr" class="dropdown-header">
                                                <p>用户自定义列表&nbsp;(用英文逗号隔开)</p>
                                            </div>
                                            <div id="createuserdefined-input" class="dropdown-item-text" >
                                                    <input type="text" id="arrv1" style="min-width: 250px;" autocomplete="off" value="2,7,26,25,19,17,1,90,3,36" spellcheck="false" data-ms-editor="true">
                                                    <div id="createuserdefined-go" class="btn btn-sm btn-blue " onclick="createNlogN()" title="Create random fixed size linked list">
                                                        执行
                                                    </div>
                                            </div>                                            
                                        </div>
                                    </div>
                                    <div class="dropdown dropend">                                        
                                        <a  class="dropdown-item dropdown-toggle" href="#"_id="dropdown-create" data-bs-toggle="dropdown" aria-haspopup="true" aria-expanded="false">
                                            创建 O(N)</a>
                                        <div class="dropdown-menu" aria-labelledby="dropdown-create" style="min-width: 300px;">
                                           
                                            <div id="create-random" class="dropdown-item" onclick="createNRandom()" >
                                                <a>随机</a>
                                            </div>
                                            <div id="create-random-sorted" class="dropdown-item" onclick="createNSample()" >
                                                <a>已排序</a>
                                            </div>
                                          
                                            <div class="dropdown-divider"></div>
                                            <div id="create-from-arr" class="dropdown-header">
                                                <p>用户自定义列表&nbsp;(用英文逗号隔开)</p>
                                            </div>
                                            <div id="createuserdefined-input" class="dropdown-item-text" >
                                                    <input type="text" id="arrv2" style="min-width: 250px;"  autocomplete="off" value="2,7,26,25,19,17,1,90,3,36" spellcheck="false" data-ms-editor="true">
                                                    <div id="createuserdefined-go" class="btn btn-sm btn-blue " onclick="createN()" title="Create random fixed size linked list">
                                                        执行
                                                    </div>
                                            </div>                                            
                                        </div>
                                    </div>
                                    <div class="dropdown dropend">
                                        <a id="insert" class="dropdown-item dropdown-toggle" href="#"_id="dropdown-insert" data-bs-toggle="dropdown" aria-haspopup="true"   aria-expanded="false">
                                            插入</a>
                                        <div class="dropdown-menu " aria-labelledby="dropdown-insert" style="min-width: 200px;">
                                            <div  class="dropdown-item-text" >
                                                插入值
                                            </div>   
                                            <div id="insert-head" class="dropdown-item-text" >
                                                <input type="number" id="v" title="Enter an Integer" autocomplete="off" min="0" max="99" value="85">
                                                <div id="inserthead-go" class="btn btn-sm btn-blue " onclick="insert()" >
                                                    执行
                                                </div>                                          
                                            </div>                                           
                                        </div>  
                                    </div>
                                    <div class="dropdown dropend">
                                        <a  class="dropdown-item"  onclick="extractmax();" >
                                            提取最大值</a>                                                                 
                                    </div>
                                    <div class="dropdown dropend">
                                        <a  class="dropdown-item" onclick="heapsort();" >
                                            堆排序</a>                                                                 
                                    </div>
                                   
                                </div>
                            </div>
                        </div>
                        
                        <div class="col-auto">
                            <span id="go-to-beginning" class="media-control-button" title="go to beginning" onclick="goToBeginning()"><img
                                src="../assets/images/goToBeginning.png" alt="go to beginning"></span>
                        </div>
                        <div class="col-auto">
                            <span id="previous" class="media-control-button" title="step backward" onclick="stepBackward()"><img
                                src="../assets/images/prevFrame.png" alt="previous frame"></span>
                        </div>
                        <div class="col-auto">
                            <span id="pause" class="media-control-button" title="pause" onclick="pause()" ><img
                                src="../assets/images/pause.png" alt="pause"></span>
                            <span id="play" class="media-control-button" title="play" onclick="play()" style="display: none;">
                                <img src="../assets/images/play.png" alt="play"></span>
                        </div>
                        <div class="col-auto">
                            <span id="next" class="media-control-button" title="step forward" onclick="stepForward()"><img
                                src="../assets/images/nextFrame.png" alt="next frame"></span>
                        </div>
                        <div class="col-auto">
                            <span id="go-to-end" class="media-control-button" title="go to end" onclick="goToEnd()"><img
                                src="../assets/images/goToEnd.png" alt="go to end"></span>
                        </div>


                        <div class="col-5 me-auto">
                            <div id="progress-bar" class="slider ui-slider ui-slider-horizontal ui-widget ui-widget-content ui-corner-all" data-min="0" data-max="1800" data-value="223">
                            </div>

                        </div>
                        <div class="col-auto">
                            <div class="btn-group dropdown dropup">
                                <a id="codetrace-toggle" class="btn btn-sm btn-warning dropdown-toggle" data-bs-toggle="dropdown" data-bs-auto-close="false" aria-expanded="false" data-bs-offset="0,20">                            
                                    代码跟踪
                                                  
                                </a>
                                <div id="codetrace-panel" class="dropdown-menu dropdown-menu-end">
                                    <div class="row" style="width: 600px;">
                                        <div class="col-sm-12">
                                            <div id="status" class=" col-sm-12" >
                                                <p></p>
                                            </div>
                                            <div id="codetrace" class=" col-sm-12">
                                                <p id="code1" style="padding-top: 10px; background-color: rgb(82, 188, 105); color: rgb(255, 255, 255);"></p>
                                                <p id="code2" style="background-color: rgb(82, 188, 105); color: rgb(255, 255, 255);"></p>
                                                <p id="code3" style="background-color: rgb(82, 188, 105); color: rgb(255, 255, 255);"></p>
                                                <p id="code4" style="background-color: rgb(82, 188, 105); color: rgb(255, 255, 255);"></p>
                                                <p id="code5" style="background-color: rgb(82, 188, 105); color: rgb(255, 255, 255);"></p>
                                                <p id="code6" style="background-color: rgb(82, 188, 105); color: rgb(255, 255, 255);"></p>
                                                <p id="code7" style="padding-bottom: 10px; background-color: rgb(82, 188, 105); color: rgb(255, 255, 255);"></p>
                                            </div>
                                        </div>
                                    </div>
                                </div>

                            </div>
                        </div>
                       </div>
            </footer>
        </div>
    </div>    

    <div class="page-loading-overlay">
        <div class="loader-2"></div>
    </div>

  


    <!-- Bottom Scripts -->
    <script src="../assets/js/bootstrap.bundle.js"></script>
    <script src="../assets/js/bootstrap5.dropdown.ml.hack.js"></script>
    <script src="../assets/js/TweenMax.min.js"></script>
    <script src="../assets/js/resizeable.js"></script>
    <script src="../assets/js/joinable.js"></script>
    <script src="../assets/js/xenon-api.js"></script>
    <script src="../assets/js/xenon-toggles.js"></script>


    <!-- Imported scripts on this page -->
    <script src="../assets/js/xenon-widgets.js"></script>
    <script src="../assets/js/devexpress-web-14.1/js/globalize.min.js"></script>
    <!--   <script src="../assets/js/devexpress-web-14.1/js/dx.chartjs.js"></script>-->
    <script src="../assets/js/toastr/toastr.min.js"></script>


    
    <script src="../assets/js/jquery-ui/jquery-ui.js"></script>
    <script src="../assets/js/knob/jquery.knob.min.js"></script>

    <!-- JavaScripts initializations and stuff -->
    <script src="../assets/js/xenon-custom.js"></script>
    
    <script src="../assets/js/d3.min.js"></script>
    <script src="../assets/js/viz-1.0.3.js"></script>
    <script src="../assets/js/visualgo_print.js"></script>
    <script src="../assets/js/graph_library.js"></script>

    <script type="text/javascript">
        // Heap Widget
        // original author: Steven Halim
        
        var Heap = function() {
          var gw = new GraphWidget();
        
          /*
           * A: Internal representation of Heap in this object
           * It is a compact 1-based 1-dimensional array (ignoring index 0)
           * The parent/left child/right child can be computed via index manipulation
           *
           * Elements of A are ObjectPair objects, where first element is the value and the second element is the ID of the vertex SVG corresponding to the value
           */
        
          /*
           * Edge IDs are the index of the child element, so for example edge A[1]-A[2] will have ID "e2" (edge 2)
           * The edges will be set to not change when vertexes are interchanged
           * This eliminates the need to maintain an Adjacency Matrix / List
           */
        
          var coord = new Array();
          var A = new Array();
          var amountVertex = 0;
          var arr;
        
          initArrayRandom();
          init();
        
          var stateList = [];
        
          this.getGraphWidget = function() { return gw; };
        
          function parent(i) { return i>>1; } // Math.floor(i/2);
        
          function left(i) { return i<<1; } // i*2;
        
          function right(i) { return (i<<1)+1; } // i*2+1;
          
          this.IsMaxHeap = function(array) {
            for (var i = 1; i < array.length; i++)
              if (array[parent(i)] < array[i])
                return false;
           return true;
          }
        
          this.generate = function(array) {
            clearScreen();
            array.unshift(999999);
            A = [];
            for (var i = 0; i < array.length; i++) {
              A[i] = new ObjectPair(array[i], amountVertex); // testing layout, to leave the edges there for now
              amountVertex++;
            }
            init();
          };
        
          this.saveArray = function() {
            arr = new Array();
            for (var i = 0; i < A.length; i++)
              arr[i] = A[i].getFirst();
            return arr;
          }
        
          this.restoreArray = function(arr) {
            clearScreen();
            amountVertex = arr.length;
            A = [];
            for (var i = 0; i < amountVertex; i++)
              A[i] = new ObjectPair(arr[i], i);
            init();
          }
        
          function initArrayRandom() {
            A = [];
            amountVertex = 5 + Math.floor(Math.random()*11); // [5..15]
            A[0] = new ObjectPair(999999, 0);
            arr = new Array();
            for (var i = 1; i < amountVertex; i++) {
              var lb = 20;
                   if (i == 1)           lb = 80;
              else if (i >= 2 && i <= 3) lb = 60;
              else if (i >= 4 && i <= 7) lb = 40;
              var newVal = lb + Math.floor(Math.random()*20); // [lb..lb+19]
              while ($.inArray(newVal, arr) != -1)
                newVal = lb + Math.floor(Math.random()*20);
              arr.push(newVal);
              A[i] = new ObjectPair(newVal, i);
            }
          }
        
          this.createRandom = function() {
            clearScreen();
            initArrayRandom();
            init();
          }
        
          function init() {
            var i, j;
        
            // compute vertex coordinates  
            var vtx_count = 1; // 1-based indexing
            for (i = 0; i <= 4; i++) { // we limit our visualization to 4 levels only
              var entriesInThisLevel = 1<<i; // 2^i
              for (j = 0; j < entriesInThisLevel; j++) {
                coord[vtx_count] = new Array();
                coord[vtx_count][0] = (2*j + 1) * 900 / (2*entriesInThisLevel); // x Coordinate
                coord[vtx_count][1] = 50 + 40*i; // y Coordinate
                vtx_count++;
              }
            }
        
            for (i = 1; i < A.length; i++) // add vertices first
              gw.addVertex(coord[i][0], coord[i][1], A[i].getFirst(), A[i].getSecond(), true, i);
        
            for (i = 2; i < A.length; i++) { // then add edges, i is edge id
              parentVertex = A[parent(i)].getSecond();
              childVertex = A[i].getSecond();
              gw.addEdge(parentVertex, childVertex, i, EDGE_TYPE_UDE, 1, true);
            }
          }
        
          function clearScreen() {
            var i;
            for (i = 2; i < A.length; i++) // remove edges first
              gw.removeEdge(i);
            for (i = 1; i < A.length; i++) // then afterwards, remove vertices
              gw.removeVertex(A[i].getSecond());
            amountVertex = 0;
            A = []; // destroy old A, create new one
          }
        
          this.insert = function(vertexText, startAnimationDirectly, callback) {
            if (A.length > 31) {
              toastr.error('抱歉，已达到上限31');
              if (typeof callback == 'function') callback();
              return false;
            }
        
            for (i = 0; i < A.length; i++) {
              if (A[i].getFirst() == parseInt(vertexText)) {
                toastr.error('抱歉，堆中已经包含该值。包含重复值的堆无法演示');
                if (typeof callback == 'function') callback();
                return false;
              }
            }
        
            if (startAnimationDirectly == true) {
              stateList = [];
              populatePseudocode(0);
            }
        
            var i, key, cs;
            if (A.length > 1) {
              cs = createState(A);
              cs["status"] = "当前最大二叉堆";
              cs["lineNo"] = !startAnimationDirectly ? 2 : 0;
              stateList.push(cs); // zero-th frame, the starting point
            }
        
            A[A.length] = new ObjectPair(parseInt(vertexText), amountVertex);
            amountVertex++;
            i = A.length-1;
        
            cs = createState(A);
            cs["vl"][A[i].getSecond()]["state"] = VERTEX_HIGHLIGHTED;
            cs["status"] = vertexText + " 被插入到了紧凑的数组A后面.";
            cs["lineNo"] = !startAnimationDirectly ? 3 : [1, 2]; // differentiate O(N log N) build vs single insert
            stateList.push(cs); // first frame, highlight the newly inserted vertex
        
            while (i > 1 && A[parent(i)].getFirst() < A[i].getFirst()) {
              cs = createState(A);
              cs["vl"][A[i].getSecond()]["state"] = VERTEX_HIGHLIGHTED;
              cs["vl"][A[parent(i)].getSecond()]["state"] = VERTEX_TRAVERSED;
              cs["status"] = A[parent(i)].getFirst() + ' < ' + A[i].getFirst() + ', 所以交换他们的位置.';
              cs["lineNo"] = 3;
              stateList.push(cs); // before swap
        
              var temp = A[i];
              A[i] = A[parent(i)];
              A[parent(i)] = temp;
              cs = createState(A);
              cs["vl"][A[i].getSecond()]["state"] = VERTEX_TRAVERSED;
              cs["vl"][A[parent(i)].getSecond()]["state"] = VERTEX_HIGHLIGHTED;
              cs["status"] = A[parent(i)].getFirst() + ' <-> ' + A[i].getFirst() + ' 已经被交换了.';
              cs["lineNo"] = !startAnimationDirectly ? 3 : 4;
              stateList.push(cs); // record the successive vertex swap animation
              i = parent(i);
            }
        
            cs = createState(A); // record the final state of the heap after insertion to stop the highlights
            cs["vl"][A[i].getSecond()]["state"] = VERTEX_HIGHLIGHTED; // highlighted the successful insertion
            cs["status"] = vertexText + ' 已经被成功插入.';
            cs["lineNo"] = !startAnimationDirectly ? 3 : 0;
            stateList.push(cs);
        
            if (startAnimationDirectly) gw.startAnimation(stateList, callback);
            return true;
          }
        
          this.shiftDown = function(i, calledFrom) {
            while (i < A.length) {
              var maxV = A[i].getFirst(), max_id = i;
              if (left(i) < A.length && maxV < A[left(i)].getFirst()) {
                maxV = A[left(i)].getFirst();
                max_id = left(i);
              }
              if (right(i) < A.length && maxV < A[right(i)].getFirst()) {
                maxV = A[right(i)].getFirst();
                max_id = right(i);
              }
        
              if (max_id != i) {
                var cs = createState(A);
                cs["vl"][A[i].getSecond()]["state"] = VERTEX_HIGHLIGHTED;
                cs["vl"][A[max_id].getSecond()]["state"] = VERTEX_TRAVERSED;
                cs["status"] = A[i].getFirst() + ' < ' + A[max_id].getFirst() + ', 所以交换他们的位置.';
                if (calledFrom == 'extractmax')
                  cs["lineNo"] = [4, 5];
                else if (calledFrom == 'createN')
                  cs["lineNo"] = [2, 3];
                else if (calledFrom == 'heapsort')
                  cs["lineNo"] = 2;
                stateList.push(cs); // deal with affected edges first
        
                var temp = A[i];
                A[i] = A[max_id];
                A[max_id] = temp;
                cs = createState(A);
                cs["status"] = A[i].getFirst() + ' <-> ' + A[max_id].getFirst() + ' 已经被交换了.';
                if (calledFrom == 'extractmax')
                  cs["lineNo"] = 6;
                else if (calledFrom == 'createN')
                  cs["lineNo"] = [2, 3];
                else if (calledFrom == 'heapsort')
                  cs["lineNo"] = 2;
                stateList.push(cs);
        
                i = max_id;
              }
              else
                break;
            }
          }
        
          this.getMax = function() { return A[1].getFirst(); }
        
          this.extractMax = function(startAnimationDirectly, callback) {
            if (A.length == 2) {
              toastr.error('抱歉，最大二叉堆只剩这一个元素了.');
              if (typeof callback == 'function') callback();
              return false;
            }
        
            if (startAnimationDirectly == true) {
              stateList = [];
              populatePseudocode(1);
            }
        
            var cs = createState(A);
            cs["vl"][A[1].getSecond()]["state"] = VERTEX_HIGHLIGHTED;
            cs["status"] = '根元素储存的是最大的元素.';
            cs["lineNo"] = !startAnimationDirectly ? 2 : 0; // heapsort vs standard extract
            stateList.push(cs); // highlight the root (max element)
        
            cs = createState(A);
            delete cs["vl"][A[1].getSecond()];
            var maxitem = A[1].getFirst();
            cs["status"] = '拿出根元素 ' + maxitem + '.';
            cs["lineNo"] = !startAnimationDirectly ? 2 : 1;
            stateList.push(cs); // move the root (max element) a bit upwards (to simulate 'extract max')
        
            if (A.length > 2) {
              cs = createState(A);
              delete cs["vl"][A[1].getSecond()];
              cs["status"] = '用最后一个叶元素替换根元素 ' + A[A.length-1].getFirst() + '.';
              cs["vl"][A[A.length-1].getSecond()]["state"] = VERTEX_HIGHLIGHTED; // highlighted the last leaf
              cs["lineNo"] = !startAnimationDirectly ? 2 : [2, 3];
              stateList.push(cs); // delete bottom-most right-most leaf (later, also remove its associated edge)
            }
        
            if (A.length > 2) {
              A[1] = A[A.length-1];
              A.splice(A.length-1, 1);
              cs = createState(A);
              cs["vl"][A[1].getSecond()]["state"] = VERTEX_HIGHLIGHTED;
              cs["status"] = '新的根.';
              cs["lineNo"] = !startAnimationDirectly ? 2 : [2, 3];
              stateList.push(cs); // highlight the new root
            }
        
            this.shiftDown(1, !startAnimationDirectly ? 'heapsort' : 'extractmax');
        
            cs = createState(A);
            cs["status"] = 'ExtractMax() 已经完成<div>返回最大元素</div>: ' + maxitem + '.';
            cs["lineNo"] = !startAnimationDirectly ? 1 : 0;
            stateList.push(cs);
        
            if (startAnimationDirectly) gw.startAnimation(stateList, callback);
            return true;
          }
        
          this.heapSort = function(callback) {
            if (A.length == 2) {
              toastr.error('抱歉，最大二叉堆只剩这一个元素了.');
              if (typeof callback == 'function') callback();
              return false;
            }
        
            populatePseudocode(2);
            res = []; // copy first
            for (var i = 1; i < A.length; i++)
              res[i-1] = A[i].getFirst();
            res.sort(function(a, b) { return a-b });
        
            stateList = [];
            var len = A.length-1;
            var partial = [];
            for (var i = 0; i < len; i++)
              partial[i] = -1;
        
            for (var i = 0; i < len-1; i++) { // except the last item (minor bug if not stopped here)
              partial[len-1-i] = A[1].getFirst();
              this.extractMax(false);
              cs = createState(A);
              cs["status"] = '部分排序的结果是 ' + partial + '.';
              cs["lineNo"] = 1;
              stateList.push(cs);
            }
        
            cs = createState(A);
            cs["status"] = '最终排序完成的结果是 ' + res + '.';
            cs["lineNo"] = 0;
            stateList.push(cs);
        
            gw.startAnimation(stateList, callback);
            return true;
          }
        
          this.createNlogN = function(arr, callback) {
            if (arr.length > 31) {
              toastr.error('抱歉，不支持演示超过31个元素的最大二叉堆.');
              if (typeof callback == 'function') callback();
              return false;
            }
        
            populatePseudocode(3);
            clearScreen();
            var i, initValue = [999999, parseInt(arr[0])];
            stateList = [];
        
            var cs = createState(A);
            cs["status"] = '从一个空的二叉堆开始.';
            cs["lineNo"] = 1;
            stateList.push(cs);
        
            for (i = 0; i < initValue.length; i++) {
              A[i] = new ObjectPair(initValue[i], amountVertex);
              amountVertex++;
            }
            init();
        
            cs = createState(A);
            cs["status"] = arr[0] + ' 已经被插入了<div>它变成了新的根元素</div>.';
            cs["lineNo"] = [2, 3];
            stateList.push(cs);
        
            for (i = 1; i < arr.length; i++) // insert one by one
              this.insert(parseInt(arr[i]), false);
        
            cs = createState(A);
            cs["status"] = '已经成功从数组A创建了最大二叉堆: ' + arr + '.';
            cs["lineNo"] = 0;
            stateList.push(cs);
        
            gw.startAnimation(stateList, callback);
            return true;
          }
        
          this.createN = function(arr, callback) {
            if (arr.length > 31) {
             toastr.error('抱歉，不支持演示超过31个元素的最大二叉堆.');
              if (typeof callback == 'function') callback();
              return false;
            }
        
            populatePseudocode(4);
            clearScreen();
            var i, initValue = [999999];
        
            for (i = 0; i < arr.length; i++)
              initValue[i+1] = parseInt(arr[i]);
        
            for (i = 0; i < initValue.length; i++) {
              A[i] = new ObjectPair(initValue[i], amountVertex);
              amountVertex++;
            }
            init();
        
            stateList = [];
            var cs = createState(A);
            cs["status"] = '保持数组A本来的样子（一个完整的二叉树结构）.';
            cs["lineNo"] = 1;
            stateList.push(cs);
        
            for (i = Math.floor(arr.length/2); i >= 1; i--) { // check heap property one by one
              cs = createState(A);
              cs["vl"][A[i].getSecond()]["state"] = VERTEX_HIGHLIGHTED;
              cs["status"] = 'shiftDown(' + i + ') 来修正以此为根的份树的大优先二叉树特性（如果需要的话） ' + A[i].getFirst() + '.';
              cs["lineNo"] = [2, 3];
              stateList.push(cs);
        
              this.shiftDown(i, 'createN');
            }
        
            cs = createState(A);
            cs["status"] = '已经成功从数组A创建了最大二叉堆: ' + arr + '.';
            cs["lineNo"] = 0;
            stateList.push(cs);
        
            gw.startAnimation(stateList, callback);
            return true;
          }
        
          function createState(iH) {
            var s = {
              "vl": {},
              "el": {},
            };
        
            for (var i = 1; i < iH.length; i++) {
              var key = iH[i].getSecond();
              s["vl"][key] = {};
              s["vl"][key]["cx"] = coord[i][0];
              s["vl"][key]["cy"] = coord[i][1];
              s["vl"][key]["text"] = iH[i].getFirst();
              s["vl"][key]["extratext"] = i; // the vertex number
              s["vl"][key]["state"] = VERTEX_DEFAULT;
            }
        
            for (var i = 2; i < iH.length; i++) {
              s["el"][i] = {};
              s["el"][i]["vertexA"] = iH[parent(i)].getSecond();
              s["el"][i]["vertexB"] = iH[i].getSecond();
              s["el"][i]["type"] = EDGE_TYPE_UDE;
              s["el"][i]["weight"] = 1;
              s["el"][i]["state"] = EDGE_DEFAULT;
              s["el"][i]["animateHighlighted"] = false;
            }
        
            return s;
          }
        
          function populatePseudocode(act) {
            switch (act) {
              case 0: // Insert
                $('#code1').html('A[A.length] = v');
                $('#code2').html('i = A.length-1');
                $('#code3').html('while ((i &gt; 1) &amp;&amp; (A[i] &gt; A[parent(i)]))');
                $('#code4').html('&nbsp&nbspswap(A[i], A[parent(i)]); i = parent(i)');
                $('#code5').html('');
                $('#code6').html('');
                $('#code7').html('');
                break;
              case 1: // ExtractMax
                $('#code1').html('拿出 A[1]');
                $('#code2').html('A[1] = A[A.length-1]');
                $('#code3').html('i = 1; A.length--');
                $('#code4').html('while (i &lt; A.length)');
                $('#code5').html('&nbsp&nbspif A[i] < (L = i 的两个下级中较大的)');
                $('#code6').html('&nbsp&nbsp&nbsp&nbspswap(A[i], L); i = L&#39;s index');
                $('#code7').html('');
                break;
              case 2: // HeapSort
                $('#code1').html('for (i = 0; i &lt; A.length; ++i)');
                $('#code2').html('&nbsp&nbspextractMax()');
                $('#code3').html('');
                $('#code4').html('');
                $('#code5').html('');
                $('#code6').html('');
                $('#code7').html('');
                break;
              case 3: // Create, O(N log N)
                $('#code1').html('start from an empty heap');
                $('#code2').html('for (i = 0; i &lt; A.length; ++i)');
                $('#code3').html('&nbsp&nbspinsert(A[i])');
                $('#code4').html('');
                $('#code5').html('');
                $('#code6').html('');
                $('#code7').html('');
                break;
              case 4: // Create, O(N)
                $('#code1').html('数组A本来的样子');
                $('#code2').html('for (i = A.length/2; i &gt;= 1; --i)');
                $('#code3').html('&nbsp&nbsp<span style="white-space: normal;">shiftDown(i)&nbsp; //下移</span><br>');
                $('#code4').html('');
                $('#code5').html('');
                $('#code6').html('');
                $('#code7').html('');
                break;
            }
          }
        }
        
        
        
        // Heap Actions
        var actionsWidth = 150;
        var statusCodetraceWidth = 370;
        
        var isCreateNlogNOpen = false, isCreateNOpen = false, isInsertOpen = false, isExtractmaxOpen = false, isHeapsortOpen = false;
        
        function opencreateNlogN() {
          if (!isCreateNlogNOpen){
            $('.createNlogN').fadeIn('fast');
            isCreateNlogNOpen = true;
          }
        }
        
        function closeCreateNlogN() {
          if (isCreateNlogNOpen) {
            $('.createNlogN').fadeOut('fast');
        
            isCreateNlogNOpen = false;
          }
        }
        
        function opencreateN() {
          if (!isCreateNOpen) {
            $('.createN').fadeIn('fast');
            isCreateNOpen = true;
          }
        }
        
        function closeCreateN() {
          if (isCreateNOpen) {
            $('.createN').fadeOut('fast');
        
            isCreateNOpen = false;
          }
        }
        
        function openInsert() {
          if (!isInsertOpen) {
            $('.insert').fadeIn('fast');
            isInsertOpen = true;
          }
        }
        
        function closeInsert() {
          if (isInsertOpen) {
            $('.insert').fadeOut('fast');
          
            isInsertOpen = false;
          }
        }
        
        function openExtractmax() {
          if (!isExtractmaxOpen) {
            $('.extractmax').fadeIn('fast');
            isExtractmaxOpen = true;
          }
        }
        
        function closeExtractmax() {
          if (isExtractmaxOpen) {
            $('.extractmax').fadeOut('fast');
         
            isExtractmaxOpen = false;
          }
        }
        
        function openHeapsort() {
          if (!isHeapsortOpen) {
            $('.heapsort').fadeIn('fast');
            isHeapsortOpen = true;
          }
        }
        
        function closeHeapsort() {
          if (isHeapsortOpen) {
            $('.heapsort').fadeOut('fast');
            
            isHeapsortOpen = false;
          }
        }
        
        function hideEntireActionsPanel() {
          closeCreateNlogN();
          closeCreateN();
          closeInsert();
          closeExtractmax();
          closeHeapsort();
          hideActionsPanel();
        }
        
        
        
        // local
        $('#play').hide();
        var hw = new Heap();
        var gw = hw.getGraphWidget();
        
        $(function() {
          var createHeap = getQueryVariable("create");
          if (createHeap.length > 0) {
            var newHeap = createHeap.split(",");
            if (hw.IsMaxHeap(newHeap)) // the input parameter is already a max heap
              hw.generate(newHeap); // just show
            else {
              $('#arrv2').val(createHeap);
              createN(); // not yet a max heap, build it fast
              stop();
            }
          }
        
          $('#createNlogN').click(function() {
            closeCreateN();
            closeInsert();
            closeExtractmax();
            closeHeapsort();
            opencreateNlogN();
          }); 
        
          $('#createN').click(function() {
            closeCreateNlogN();
            closeInsert();
            closeExtractmax();
            closeHeapsort();
            opencreateN();
          });
        
          $('#insert').click(function() {
            closeCreateNlogN();
            closeCreateN();
            closeExtractmax();
            closeHeapsort();
            openInsert();
          });
          
          $('#extractmax').click(function() {
            closeCreateNlogN();
            closeCreateN();
            closeInsert();
            closeHeapsort();
            openExtractmax();
          });
          
          $('#heapsort').click(function() {
            closeCreateNlogN();
            closeCreateN();
            closeInsert();
            closeExtractmax();
            openHeapsort();
          });
        });
        
        function createNlogNWithInput(input, callback) {
          commonAction(hw.createNlogN(input.split(","), callback), "创建 - O(N log N): " + input);
        }
        
        function createNlogN(callback) {
          if (isPlaying) stop();
          var input = $('#arrv1').val();
          createNlogNWithInput(input, callback);
        }
        
        function createNlogNSample(callback) {
          if (isPlaying) stop();
          var input = "1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31";
          createNlogNWithInput(input, callback);
        }
        
        function createNlogNRandom(callback) {
          if (isPlaying) stop();
          var n = 7 + Math.floor(17*Math.random());
          var input = new Array();
          while (n > 0) {
            var newVal = 1 + Math.floor(98*Math.random());
            if ($.inArray(newVal, input) == -1) {
              input.push(newVal);
              n--;
            }
          }
          input = input.join(",");
          createNlogNWithInput(input, callback);
        }
        
        function createNWithInput(input, callback) {
          commonAction(hw.createN(input.split(","), callback), "创建 - O(N): " + input);
        }
        
        function createN(callback) {
          if (isPlaying) stop();
          var input = $('#arrv2').val();
          createNWithInput(input, callback);
        }
        
        function createNSample(callback) {
          if (isPlaying) stop();
          var input = "1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31";
          createNWithInput(input, callback);
        }
        
        function createNRandom(callback) {
          if (isPlaying) stop();
          var n = 7 + Math.floor(17*Math.random());
          var input = new Array();
          while (n > 0) {
            var newVal = 1 + Math.floor(98*Math.random());
            if ($.inArray(newVal, input) == -1) {
              input.push(newVal);
              n--;
            }
          }
          input = input.join(",");
          commonAction(hw.createN(input.split(","), callback), "创建 - O(N): " + input);
        }
        
        function insert(callback) {
          if (isPlaying) stop();
          var input = parseInt($("#v").val());
          commonAction(hw.insert(input, true, callback), "插入 " + input);
          setTimeout(function() { 
            var existing = hw.saveArray();
            var next_num = 1 + Math.floor(Math.random()*88);
            while (existing.includes(next_num)) next_num = 1 + Math.floor(Math.random()*88);
            $("#v").val(next_num); // randomized for next click between [1..89}, and it won't exist before (allow for a few more insertion of 90-99, still two digits)
          }, 500);
        }
        
        function insert_top(callback) {
          if (isPlaying) stop();
          var input = hw.getMax()+1; // always increase the top value by 1
          commonAction(hw.insert(input, true, callback), "插入 " + input);
          setTimeout(function() { $("#v").val(1 + Math.floor(Math.random()*98)); }, 500); // randomized for next click between [1..99}
        }
        
        function extractmax(callback) {
          if (isPlaying) stop();
          commonAction(hw.extractMax(true, callback), "提取最大值");
        }
        
        function heapsort(callback) {
          if (isPlaying) stop();
          commonAction(hw.heapSort(callback), "堆排序");
        }
        
        var exploreModeData = [];
        
        // This function will be called before entering e-Lecture Mode
        function ENTER_LECTURE_MODE() {
          exploreModeData = hw.saveArray();
        }
        
        // This function will be called before returning to Explore Mode
        function ENTER_EXPLORE_MODE() {
          hw.restoreArray(exploreModeData);
        }
        
        // Lecture action functions
        function CUSTOM_ACTION(action, data, mode) {
          if (action == 'random_insert') {
            hideSlide(function() {
              insert(showSlide);
            });
          }
          else if (action == 'insert_top') {
            hideSlide(function() {
              insert_top(showSlide);
            });
          }
          else if (action == 'extractmax') {
            hideSlide(function() {
              extractmax(showSlide);
            });
          }
          else if (action == 'createN') {
            hideSlide(function() {
              createNWithInput(data, showSlide);
            });
          }
          else if (action == 'createNlogN') {
            hideSlide(function() {
              createNlogNWithInput(data, showSlide);
            });
          }
          else if (action == 'heapsort') {
            hideSlide(function() {
              heapsort(showSlide);
            });
          }
        }
        </script>      

</body>

</html>